package com.third.bank.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.third.bank.Dto.TransactionRecordsDto;
import com.third.bank.Dto.TransferDto;
import com.third.bank.entity.Balance;
import com.third.bank.entity.TransactionRecords;
import com.third.bank.entity.User;
import com.third.bank.exception.BusinessException;
import com.third.bank.mapper.TransactionRecordsMapper;
import com.third.bank.service.BalanceService;
import com.third.bank.service.TransactionRecordsService;
import com.third.bank.service.UserService;
import com.third.bank.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 交易记录表serviceimpl
 */
@Slf4j
@Service
public class TransactionRecordsServiceimpl extends ServiceImpl<TransactionRecordsMapper, TransactionRecords> implements TransactionRecordsService {
    @Autowired
    private UserService userService;
    @Autowired
    private BalanceService balanceService;

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
    public BaseResponse transfer(TransferDto trans) {

        System.out.println(trans);
        String userBankcard = trans.getUserBankcard();
        User user = userService.searchUserbycard(userBankcard);
        //判断用户登录状态
        if (user.getLoginStatus() == 0) {
            //用户未登录，返回未登录提示信息
            return ResultUtils.error(0, "未登录，无法转账");
        }
        // String password = JwtUtil.parse(trans.getPassword());
        String reuserBankcard = trans.getReuserBankcard();
        User reuser = userService.searchUserbycard(reuserBankcard);
        //判断接收账户是否存在
        if (reuser == null) {
            //接收账户不存在，返回接收账户不存在
            return ResultUtils.error(0, "接收账户不存在");
        }
        //判断转账账号与接收姓名的一致性
        if (!reuser.getUsername().equals(trans.getName())) {
            //接收账户与接收姓名不匹配，返回不匹配提示信息
            return ResultUtils.error(0, "转账账户和姓名不匹配");
        }
        //判断转账密码正确性
        if (!MD5Util.getMD5(trans.getPassword()).equals(user.getWdPassword())) {
            //输入转账密码错误，返回密码错误提示信息
            return ResultUtils.error(0, "密码错误");
        }
        //根据用户id查询账户余额
        Balance userBalance = balanceService.searchBalancebyID(user.getId());
        Balance reuserBalance = balanceService.searchBalancebyID(reuser.getId());
        //查询用户余额度
        if (userBalance.getBalance().subtract(new BigDecimal(trans.getAccount())).intValue() < 0) {
            //用户余额不足，返回余额不足提示信息
            return ResultUtils.error(0, "余额不足");
        }
        try {
            BigDecimal account = new BigDecimal(trans.getAccount());
            LocalDateTime date = LocalDateTime.now();
            userBalance.setBalance(userBalance.getBalance().subtract(account));
            userBalance.setUpdateTime(date);
            reuserBalance.setBalance(reuserBalance.getBalance().add(account));
            reuserBalance.setUpdateTime(date);
            //根据用户id更新用户余额度与更新时间
            balanceService.updateBalancebyID(user.getId(), userBalance);
            //根据用户id更新接收账户的余额与更新时间
            balanceService.updateBalancebyID(reuser.getId(), reuserBalance);
            //创建转账交易记录
            TransactionRecords userTransactionrecords = new TransactionRecords(new Long(0), user.getId(), LocalDateTime.now(), 3, account.negate(), userBalance.getBalance(), reuser.getUsername(), reuser.getBankCard(), LocalDateTime.now());
            TransactionRecords reuserTransactionrecords = new TransactionRecords(new Long(0), reuser.getId(), LocalDateTime.now(), 3, account, reuserBalance.getBalance(), user.getUsername(), user.getBankCard(), LocalDateTime.now());
            //写入转账交易记录
            baseMapper.insert(userTransactionrecords);
            baseMapper.insert(reuserTransactionrecords);
        } catch (Exception ex) {
            //如果在转账过程中出现异常，则回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            //如在转账过程中出现异常，返回转账失败提示信息
            return ResultUtils.error(0, "转账失败");
        }
        //转账成功，返回成功结果
        return ResultUtils.success(null);
    }


    @Override
    public BaseResponse<Page<TransactionRecords>> getPageTransactionRecords(TransactionRecordsDto transactionRecordsDto, String authorization) {
        // 1、校验参数
        if (ObjectUtil.isEmpty(transactionRecordsDto)) {
            throw new BusinessException(ErrorMessage.PARAMS_ERROR);
        }

        LocalDateTime startTime = transactionRecordsDto.getStartTime();
        LocalDateTime endTime = transactionRecordsDto.getEndTime();
        Integer businessType = transactionRecordsDto.getBusinessType();
        String counterpartName = transactionRecordsDto.getCounterpartName();
        String counterpartAccount = transactionRecordsDto.getCounterpartAccount();
        Integer pageNum = transactionRecordsDto.getPageNum();
        Integer pageSize = transactionRecordsDto.getPageSize();
        // 2、验证用户 todo
        String cardId = JwtUtil.parse(authorization);
        User user = userService.searchUserbyIdcard(cardId);
        if (ObjectUtil.isEmpty(user)) {
            log.info("user = {}", user);
            throw new BusinessException(ErrorMessage.FORBIDDEN_ERROR);
        }
        // 构造查询条件
        Page<TransactionRecords> transactionRecordsPage = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<TransactionRecords> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(counterpartName), TransactionRecords::getCounterpartName, counterpartName)
               .like(StringUtils.isNotBlank(counterpartAccount), TransactionRecords::getCounterpartAccount, counterpartAccount)
               .eq(ObjectUtil.isNotEmpty(businessType), TransactionRecords::getBusinessType, businessType)
               .eq(TransactionRecords::getUserId, user.getId());

        int total = count(wrapper);

        transactionRecordsPage.setTotal(total);

        // 默认查询最近一个月的交易流水，最多可查询三个月内的交易流水
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime beginTime = null;
        LocalDateTime lastTime = null;
        if (startTime == null && endTime == null) {
            beginTime = now.minusMonths(1);
            lastTime = now;
        } else if (startTime != null && endTime == null) {
            beginTime = startTime;
            lastTime = startTime.plusMonths(1);
        } else if (startTime == null) {
            beginTime = endTime.minusMonths(1);
            lastTime = endTime;
        } else {
            if (endTime.isAfter(startTime.plusMonths(3))) {
                beginTime = startTime;
                lastTime = startTime.plusMonths(3);
            }else {
                beginTime = startTime;
                lastTime = endTime;
            }
        }

        wrapper.between(TransactionRecords::getCreatedTime, beginTime, lastTime);

        wrapper.orderByDesc(TransactionRecords::getCreatedTime);


        page(transactionRecordsPage, wrapper);


        return ResultUtils.success(transactionRecordsPage);

    }
}
